#include "PolygonAddTool.h"
#include "Actions/PolygonCreateAction.h"
#include "Actions/VertexCreateAction.h"
#include "EditorCore/IProvider.h"

using namespace cmn;
using namespace input;
using namespace editor_core;

PolygonAddTool::PolygonAddTool( BodyEntity* parentBody ) :
	m_tempAction( 0 ),
	m_parentBody( parentBody )
{}

PolygonAddTool::~PolygonAddTool() {
	if( m_tempAction ) {
		m_tempAction->Undo();
		delete m_tempAction;
	}
}

IAction* PolygonAddTool::Activate() { return 0; }

IAction* PolygonAddTool::Deactivate() {
	return CreateAction( m_vertices, m_parentBody );
}

IAction* PolygonAddTool::ProcessMouseMove( MouseMoveEventArgs* mouseMoveEventArgs ) { return 0; }
IAction* PolygonAddTool::ProcessMouseButtonPress( MouseButtonEventArgs* mouseButtonEventArgs ) { return 0; }

IAction* PolygonAddTool::ProcessMouseButtonRelease( MouseButtonEventArgs* mouseButtonEventArgs ) {
	if( mouseButtonEventArgs->GetButton() == MouseButton::Left ) {
		Mouse mouse = mouseButtonEventArgs->GetMouseState();
		Vec2 mousePos = mouse.GetPosition();

		m_vertices.Add( mousePos );

		RefreshTempAction( m_vertices, m_parentBody );
		return 0;
	}
	return 0;
}

IAction* PolygonAddTool::ProcessMouseScroll( MouseScrollEventArgs* mouseScrollEventArgs ) { return 0; }
IAction* PolygonAddTool::ProcessKeyPress( KeyEventArgs* keyEventArgs ) { return 0; }
IAction* PolygonAddTool::ProcessKeyRelease( KeyEventArgs* keyEventArgs ) { return 0; }

void PolygonAddTool::RefreshTempAction( const IIterable<Vec2>& vertices, BodyEntity* parentBody ) {
	if( m_tempAction != 0 ) {
		m_tempAction->Undo();
		delete m_tempAction;
		m_tempAction = 0;
	}

	m_tempAction = CreateAction( vertices, parentBody );
	m_tempAction->Do();
}

IAction* PolygonAddTool::CreateAction( const IIterable<Vec2>& vertices, BodyEntity* parentBody ) {
	Vec2 center = CalculateCenter( vertices );
	ListAction* listAction = new ListAction();
	PolygonCreateAction* polygonCreateAction = new PolygonCreateAction( Transform( center, 0.0f ), parentBody );
	listAction->AddAction( polygonCreateAction );
	for( IteratorPtr<Vec2> verticesIter( vertices );
			!verticesIter.IsEnd();
			verticesIter.Next() )
	{
		VertexCreateAction* vertexCreateAction = new VertexCreateAction( verticesIter.Current() - center, polygonCreateAction );
		listAction->AddAction( vertexCreateAction );
	}
	return listAction;
}

Vec2 PolygonAddTool::CalculateCenter( const IIterable<Vec2>& vertices ) {
	Vec2 sum;
	for( IteratorPtr<Vec2> verticesIter( vertices );
			!verticesIter.IsEnd();
			verticesIter.Next() )
	{
		sum += verticesIter.Current();
	}
	sum /= float( vertices.GetLength() );
	return sum;
}
